MethodChannel:用於雙向的方法呼叫,包括呼叫另一端的方法、響應另一端的呼叫,流程與 BasicMessageChannel 類似,只是資料轉換上略有不同,呼叫另一端的方法使用invokeMethod 函式,setMethodCallHandler 用於註冊一個MessageHandler來供 Native 端呼叫
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
  assert(method != null);
  final ByteData result = await binaryMessenger.send(
    name,
    codec.encodeMethodCall(MethodCall(method, arguments)),
  );
  if (result == null) {
    throw MissingPluginException('No implementation found for method $method on channel $name');
  }
  final T typedResult = codec.decodeEnvelope(result);
  return typedResult;
}
invokeMethod 有兩個引數,方法名和方法要代入的引數,在 MethodCannel中這兩個引數會被封裝成 MethodCall物件,然後利用對應的 MethodCodec 將 MethodCall 編碼成 ByteData 傳遞到 binaryMessenger,並得到 ByteData 型別的返回值,後面再利用 MethodCodec 將其解碼成泛型 T 類型資料
MethodCodec相對於MessageCode多了兩個函式,分別用於編解碼MethodCall和編解碼方法呼叫的返回值
setMethodCallHandler用於向 binaryMessenger 用於註冊一個MessageHandler來供 Native 端呼叫
void setMethodCallHandler(Future<dynamic> handler(MethodCall call)) {
  binaryMessenger.setMessageHandler(
    name,
    handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),
  );
}
Future<ByteData> _handleAsMethodCall(ByteData message, Future<dynamic> handler(MethodCall call)) async {
  final MethodCall call = codec.decodeMethodCall(message);
  try {
    return codec.encodeSuccessEnvelope(await handler(call));
  } on PlatformException catch (e) {
    return codec.encodeErrorEnvelope(
      code: e.code,
      message: e.message,
      details: e.details,
    );
  } on MissingPluginException {
    return null;
  } catch (e) {
    return codec.encodeErrorEnvelope(code: 'error', message: e.toString(), details: null);
  }
}
它會將 handler 封裝到 callback 函式中,在 _handleAsMethodCall 中進行協調,也就是先把 message 轉成 MethodCall 物件之後,再交給 handler 處理,處理完的結果再由 codec 轉成 ByteData 並返回,接著 binaryMessenger 再拿著這個資料回傳到 Native 端